﻿using Tszy.Unlimited.Base.Infrastructure.Domain;

namespace Tszy.Unlimited.Data.EntityFramework;

/// <summary>
/// EF 仓储。
/// </summary>
public interface IEntityFrameworkRepository : IRepository
{
    /// <summary>
    /// EF 上下文。
    /// </summary>
    IEntityFrameworkContext Context { get; }

    /// <summary>
    /// 增加。
    /// </summary>
    /// <typeparam name="TEntity">实体类型。</typeparam>
    /// <param name="entity">实体。d</param>
    /// <param name="cancellationToken"></param>
    Task AddAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = default) where TEntity : class, IAggregateRoot;

    /// <summary>
    /// 删除。
    /// </summary>
    /// <typeparam name="TEntity">实体类型。</typeparam>
    /// <param name="entity">实体。</param>
    Task RemoveAsync<TEntity>(TEntity entity) where TEntity : class, IAggregateRoot;

    /// <summary>
    /// 获得实体。
    /// </summary>
    /// <typeparam name="TEntity">实体类型。</typeparam>
    /// <param name="identity">唯一标识。</param>
    /// <param name="cancellationToken"></param>
    /// <returns>实体。</returns>
    Task<TEntity> GetAsync<TEntity>(object identity, CancellationToken cancellationToken = default) where TEntity : class, IAggregateRoot;

    /// <summary>
    /// 搜索实体。
    /// </summary>
    /// <typeparam name="TEntity">实体类型。</typeparam>
    /// <returns>查询对象。</returns>
    IQueryable<TEntity> Query<TEntity>() where TEntity : class, IAggregateRoot;
}

/// <summary>
/// EF 实现仓储。
/// </summary>
public class EntityFrameworkRepository : IRepository, IEntityFrameworkRepository
{
    /// <summary>
    /// EF 实体上下文。
    /// </summary>
    private readonly IEntityFrameworkContext _context;

    /// <summary>
    /// 初始化 EntityFramework 仓储。
    /// </summary>
    /// <param name="context"></param>
    public EntityFrameworkRepository(IEntityFrameworkContext context)
    {
        _context = context;
    }

    /// <summary>
    /// 唯一标识。
    /// </summary>
    public virtual Guid UniqueId => _context.UniqueId;

    /// <summary>
    /// EF 实体上下文。
    /// </summary>
    public virtual IEntityFrameworkContext Context => _context;

    /// <summary>
    /// 增加。
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="entity"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public virtual async Task AddAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = default) where TEntity : class, IAggregateRoot
    {
        await _context.Set<TEntity>().AddAsync(entity, cancellationToken);
    }

    /// <summary>
    /// 删除。
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="entity"></param>
    public virtual async Task RemoveAsync<TEntity>(TEntity entity) where TEntity : class, IAggregateRoot
    {
        await Task.FromResult(_context.Set<TEntity>().Remove(entity));
    }

    /// <summary>
    /// 查询。
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    public virtual IQueryable<TEntity> Query<TEntity>() where TEntity : class, IAggregateRoot
    {
        return _context.Set<TEntity>();
    }

    /// <summary>
    /// 获得实体。
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="identity"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public virtual async Task<TEntity> GetAsync<TEntity>(object identity, CancellationToken cancellationToken = default) where TEntity : class, IAggregateRoot
    {
        return await _context.Set<TEntity>().FindAsync(new object[] { identity }, cancellationToken);
    }
}